﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using ESpace;

namespace AMVCommander
{
    class AMVCollection
    {
        int ActVer = 0;

        List<AMV> amvL = new List<AMV>();
        public AMV this[int ind] { get { return amvL[ind]; } }
        string fPath;

        public AMVCollection(string fPath)
        {
            this.fPath = fPath;
            if (File.Exists(fPath))
            {
                EStream st = new EStream(fPath);
                st.OpenLoad();
                int ver = st.LoadInt(); // задел на версию
                Load0(st);
                st.Close();
            }
        }

        public int Count { get { return amvL.Count; } }
        public void Add(AMV amv) { amvL.Add(amv); }
        public void RemoveAt(int ind) { amvL.RemoveAt(ind); }
        public void Remove(AMV amv) { amvL.Remove(amv); }
        public void Clear() { amvL.Clear(); }

        #region *** Save/Load *************************************
        public void Save()
        {
            EStream st = new EStream(fPath);
            st.OpenSave();
            st.SaveInt(ActVer); // задел на версию

            st.SaveInt(amvL.Count);
            for (int i = 0; i < amvL.Count; i++)
                amvL[i].Save(st);

            st.Close();
        }

        void Load0(EStream st)
        {
            int kolvo = st.LoadInt();
            for (int i = 0; i < kolvo; i++)
                amvL.Add(new AMV(st));
        }
        #endregion *** Save/Load *************************************

        public List<String> GetAllTags()
        {
            List<String> ret = new List<String>();
            foreach (AMV a in amvL)
                foreach (String tag in a.Tags)
                    if (!ret.Contains(tag))
                        ret.Add(tag);
            ret.Sort();
            return ret;
        }

        public List<String> GetAllKeyWords()
        {
            List<String> ret = new List<String>();
            foreach (AMV a in amvL)
                foreach (String KeyWord in a.KeyWords)
                    if (ret.IndexOf(KeyWord) == -1)
                        ret.Add(KeyWord);
            ret.Sort();
            return ret;
        }

        public List<String> GetAllAutors()
        {
            List<String> ret = new List<String>();
            foreach (AMV a in amvL)
                foreach (String autor in a.Atr)
                    if (ret.IndexOf(autor) == -1)
                        ret.Add(autor);
            ret.Sort();
            return ret;
        }

        public List<String> GetAllAnime()
        {
            List<String> ret = new List<String>();
            foreach (AMV a in amvL)
                foreach (String anime in a.Anm)
                    if (ret.IndexOf(anime) == -1)
                        ret.Add(anime);
            ret.Sort();
            return ret;
        }

        public List<Music> GetAllMusic()
        {
            List<Music> ret = new List<Music>();
            foreach (AMV a in amvL)
                foreach (Music m in a.Msc)
                    if (ret.IndexOf(m) == -1)
                        ret.Add(m);
            ret.Sort();
            return ret;
        }

        public List<String> GetAllMusicAutors()
        {
            List<String> ret = new List<String>();
            foreach (AMV a in amvL)
                foreach (Music m in a.Msc)
                    if (ret.IndexOf(m.Author) == -1)
                        ret.Add(m.Author);
            ret.Sort();
            return ret;
        }

        public List<String> GetAllAwards()
        {
            List<String> ret = new List<String>();
            foreach (AMV a in amvL)
                foreach (String awd in a.Awd)
                    if (!ret.Contains(awd))
                        ret.Add(awd);
            ret.Sort();
            return ret;
        }

        public int IndexOfName(String nm)
        {
            string NM = nm.ToUpper();
            for (int i = 0; i < amvL.Count; i++) if (amvL[i].Name.ToUpper() == NM) return i;
            return -1;
        }

        public int IndexOfFPath(String fPath)
        {
            string NM = fPath.ToUpper();
            for (int i = 0; i < amvL.Count; i++) if (amvL[i].FLocalPath.ToUpper() == NM) return i;
            return -1;
        }

        public int IndexOfMD5(String md5)
        {
            for (int i = 0; i < amvL.Count; i++) if (amvL[i].MD5Len == md5) return i;
            return -1;
        }

        public string GetUnicName(string srsName)
        {
            return GetUnicName(srsName, null, null);
        }

        public string GetUnicName(string srsName, AMV ExcludeAmv, AMV[] AdditionalAmvList)
        {
            int n = 0;
            string ret = srsName;

            // смотрим, нет ли уже вконце цифры в скобочках. И если есть, убираем ее и скобочки из исходного имени
            if (srsName[srsName.Length - 1] == ')')
            {
                int ind = srsName.LastIndexOf('(');
                if (ind != -1 && ind < (srsName.Length - 2))
                {
                    int tmpInt = 0;
                    if (int.TryParse(srsName.Substring(ind + 1, srsName.Length - ind - 2), out tmpInt))
                    {
                        string str = srsName.Substring(0, ind).Trim();
                        if (str != "") { srsName = str; n = tmpInt; }
                    }
                }
            }

            while (true)
            {
                #region *** получение всех AMV с такими же именами ***
                string NM = ret.ToUpper();
                List<AMV> amvDuplList = new List<AMV>();
                for (int i = 0; i < amvL.Count; i++)
                    if (amvL[i].Name.ToUpper() == NM)
                        amvDuplList.Add(amvL[i]);
                if (AdditionalAmvList != null)
                {
                    for (int i = 0; i < AdditionalAmvList.Length; i++)
                        if (AdditionalAmvList[i].Name.ToUpper() == NM)
                            amvDuplList.Add(AdditionalAmvList[i]);
                }
                #endregion *** получение всех AMV с такими же именами ***

                if (amvDuplList.Count == 0) return ret;
                bool bUnic = true;
                foreach (AMV amvDupl in amvDuplList)
                {
                    if (ExcludeAmv == null || amvDupl.MD5Len != ExcludeAmv.MD5Len)
                    {
                        bUnic = false;
                        break;
                    }
                }

                if (bUnic) return ret;

                // создание нового имени, если предыдущее занято
                n++;
                ret = srsName + "(" + n.ToString() + ")";
            }
        }

    }
}
